<?php

namespace liketp\foundation;

trait MacroTrait
{
    protected $macro;

    public function __call($method, $params)
    {
        if ($this->hasMacro($method)) {
            $target = $this->macro[$method];

            [$fn, $args] = $target;
            $params = array_merge($args, $params);

            return call_user_func_array($fn, $params);
        } else {
            return $this->_callNext($method, $params);
        }
    }

    protected function _callNext($method)
    {
        throw new \Exception('method [' . $method . '] is not exists');
    }

    public function macro($method, $fn, $args = [])
    {
        if (is_array($method)) {
            foreach ($method as $v) {
                $this->macro($v, $fn, array_merge([$v], $args));
            }
        } else {
            $this->macro[$method] = [$fn, $args];
        }
        return $this;
    }

    public function hasMacro($method)
    {
        return isset($this->macro[$method]);
    }

    public function removeMacro($method)
    {
        if ($this->hasMacro($method)) unset($this->macro[$method]);
        return $this;
    }
}
